package com.cloud.DrugManagement.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cloud.DrugManagement.client.MinioClient;
import com.cloud.DrugManagement.enums.OrderState;
import com.cloud.DrugManagement.pojo.*;
import com.cloud.DrugManagement.service.*;
import com.cloud.DrugManagement.pojo.vo.ReceiptHeaderVo;
import com.cloud.common.utils.R;
import feign.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhozixiong
 * @date 2023/02/13
 */
@Slf4j
@Api(tags = "药品")
@CrossOrigin
@RestController
@RequiredArgsConstructor
public class DrugsController {

    @Value("${minio.bucketName}")
    private String bucketName;

    private final MinioClient minio;

    private final OrderDetailsService orderDetailsService;
    private final DrugsService drugsService;
    private final ReceiptHeaderService receiptHeaderService;
    private final ReceiptMonocularService receiptMonocularService;
    private final ProductPictureService productPictureService;

    @ApiOperation("查询入库列表")
    @GetMapping({"/getReceiptHeader/{pages}", "/getReceiptHeader/{pages}/{oid}"})
    public Object getReceiptHeader(@PathVariable int pages, @PathVariable(required = false) Long oid) {
        Page page = receiptHeaderService.searchAllOrOid(pages, oid);
        return R.ok(page);
    }

    @ApiOperation("查询指定入库信息")
    @GetMapping("/getReceipt/{pages}/{oid}")
    public Object getReceipt(@PathVariable int pages, @PathVariable Long oid) {
        ReceiptHeader receiptHeader = receiptHeaderService.searchAllByOid(oid);
        Page<ReceiptMonocular> receiptMonocular = receiptMonocularService.searchReceipt(pages, oid);
        OrderDetails orderDetails = orderDetailsService.searchAllByOid(oid);
        ReceiptHeaderVo receiptHeaderVo;
        if(orderDetails.getState().equals(OrderState.DELIVERED)) {
            Double totalAmount = receiptMonocularService.searchTotalAmount(oid);
            receiptHeaderVo = new ReceiptHeaderVo(receiptHeader, totalAmount);
        }else {
            receiptHeaderVo = new ReceiptHeaderVo(receiptHeader);
        }
        Map<String, Object> map = new HashMap<>(2);
        map.put("receiptHeader", receiptHeaderVo);
        map.put("receiptMonocular", receiptMonocular);
        return R.ok(map);
    }

    @ApiOperation("录入入库信息")
    @PostMapping("/createReceiptMonocular")
    public Object createReceiptMonocular(@RequestBody ReceiptMonocular receiptMonocular) {
        OrderDetails orderDetails = orderDetailsService.searchAllByOid(receiptMonocular.getOid());
        if(orderDetails.getState().equals(OrderState.SUBMITTED)) {
            if (receiptMonocularService.updateReceiptMonocular(receiptMonocular.getOid(), receiptMonocular.getDid(), receiptMonocular.getQuantity())) {
                return R.ok();
            }else {
                return R.fail();
            }
        }else {
            return R.fail();
        }
    }

    @ApiOperation("确认入库")
    @PostMapping("/confirmReceiptHeader")
    public Object confirmReceiptHeader(@RequestBody Long oid, @RequestBody String signee) {
        OrderDetails orderDetails = orderDetailsService.searchAllByOid(oid);
        if(orderDetails.getState().equals(OrderState.SUBMITTED)) {
            receiptHeaderService.updateTimeAndSigneeByOid(signee, oid);
            //修改订单状态
            orderDetailsService.updateStateByOid(OrderState.SUBMITTED, oid);
            return R.ok();
        }else {
            return R.fail();
        }
    }

    @ApiOperation(value = "查看商品信息")
    @GetMapping({"/getDrugs/{pages}/{parameter}", "/getDrugs/{pages}"})
    public Object getDrugs(@PathVariable int pages, @PathVariable(required = false) Object parameter) {
        Page page = drugsService.adminSearchDrugs(pages, parameter);
        return R.ok(page);
    }

    @ApiOperation(value = "修改商品价格")
    @PostMapping("/updateDrugsPrice")
    public Object updateDrugsPrice(@RequestBody double price, @RequestBody int did) {
        //还差判断权限
        if(drugsService.updateRetailPriceByDid(price, did)) {
            return R.ok();
        }else {
            return R.fail();
        }
    }

    @ApiOperation(value = "修改商品信息")
    @PostMapping("/admin/updateDrugsInformation")
    public Object updateDrugsInformation(@RequestBody Drugs drugs) {
        //还差判断权限
        if(drugsService.updateAllByDid(drugs)) {
            return R.ok();
        }else {
            return R.fail();
        }
    }

    @ApiOperation(value = "指定商品的第一张图片")
    @GetMapping("/picture")
    public Object picture(HttpServletResponse response, @RequestParam("did") int did) {
        ProductPicture productPicture = productPictureService.searchByDid(did);
        InputStream in = null;
        OutputStream out = null;
        try {
            response.setContentType("image/png");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + productPicture.getUrl());
            out = response.getOutputStream();
            Response feignResponse = minio.downloadPicture(bucketName, productPicture.getUrl());
            in = feignResponse.body().asInputStream();
            int len;
            byte[] bytes = new byte[1024];
            while ((len = in.read(bytes)) > 0) {
                out.write(bytes, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "full";
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    log.error("out关闭出错");
                }
            }
            if(in != null) {
                try {
                    in.close();
                }catch (IOException e) {
                    log.error("in关闭失败");
                }
            }
        }
        return R.ok();
    }

    /**
     *  查询商品所有图片路径
     */
    @ApiOperation(value = "查询该商品的所有图片路径")
    @GetMapping("/pictureUrlList/{did}")
    public Object pictureUrlList(@PathVariable int did) {
        List<ProductPicture> list = productPictureService.searchAllByDid(did);
        return R.ok(list);
    }

    @ApiOperation(value = "根据路径查看图片")
    @GetMapping("/pictureUrl")
    public Object pictureUrl(HttpServletResponse response, @RequestParam("url") String url) {
        InputStream in = null;
        OutputStream out = null;
        try {
            response.setContentType("image/png");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + url);
            out = response.getOutputStream();
            Response feignResponse = minio.downloadPicture(bucketName, url);
            in = feignResponse.body().asInputStream();
            int len;
            byte[] bytes = new byte[1024];
            while ((len = in.read(bytes)) > 0) {
                out.write(bytes, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "full";
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    log.error("out关闭出错");
                }
            }
            if(in != null) {
                try {
                    in.close();
                }catch (IOException e) {
                    log.error("in关闭失败");
                }
            }
        }
        return R.ok();
    }

    @ApiOperation(value = "管理员添加商品")
    @PostMapping("/admin/createDrugs")
    public Object createDrugs(MultipartFile[] files, int did) {
        List<String> filenameList = minio.uploadPictures(files, bucketName);
        for(String filename : filenameList) {
            productPictureService.insert(did, filename);
        }
        return R.ok();
    }

    @ApiOperation(value = "管理员删除商品")
    @GetMapping("/admin/delDrugs/{did}")
    public Object delDrugs(@PathVariable int did) {
        //还差判断权限
        if(drugsService.delByDid(did)) {
            return R.ok();
        }else {
            return R.fail();
        }
    }
}
